using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.Design;
using System.ComponentModel;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using NBusiness.Utilities;
using System.Windows.Forms;
using System.Globalization;
using NBusiness.Properties;
using System.ComponentModel.Design;

namespace NBusiness.Data.Web.Design
{

    /// <summary>
    /// Object responsible for providing details about
    /// data binding to a specific entity object.
    /// </summary>
    public class EntityDesignerDataSourceView : DesignerDataSourceView
    {

        private EntityDataSourceDesigner _owner = null;

        /// <summary>
        /// Creates an instance of the object.
        /// </summary>
        public EntityDesignerDataSourceView(
            EntityDataSourceDesigner owner,
            string viewName)
            : base(owner, viewName)
        {
            _owner = owner;
        }

        /// <summary>
        /// Returns a set of sample data used to populate
        /// controls at design time.
        /// </summary>
        /// <param name="minimumRows">Minimum number of sample rows
        /// to create.</param>
        /// <param name="isSampleData">Returns True if the data
        /// is sample data.</param>
        public override System.Collections.IEnumerable
          GetDesignTimeData(int minimumRows, out bool isSampleData)
        {
            IDataSourceViewSchema schema = this.Schema;
            DataTable result = new DataTable();
            result.Locale = CultureInfo.InvariantCulture;

            try
            {
                // create the columns
                foreach (IDataSourceFieldSchema item in schema.GetFields())
                    result.Columns.Add(item.Name, item.DataType);

                // create sample data
                for (int index = 1; index <= minimumRows; index++)
                {
                    object[] values = new object[result.Columns.Count];
                    int colIndex = 0;
                    foreach (DataColumn col in result.Columns)
                    {
                        if (col.DataType.Equals(typeof(string)))
                            values[colIndex] = "abc";
                        else if (col.DataType.Equals(typeof(DateTime)))
                            values[colIndex] = DateTime.Today.ToShortDateString();
                        else if (col.DataType.Equals(typeof(bool)))
                            values[colIndex] = false;
                        else if (col.DataType.IsPrimitive)
                            values[colIndex] = index;
                        else if (col.DataType.Equals(typeof(Guid)))
                            values[colIndex] = Guid.Empty;
                        else if (col.DataType.IsValueType)
                            values[colIndex] =
                              Activator.CreateInstance(col.DataType);
                        else
                            values[colIndex] = null;
                        colIndex++;
                    }
                    result.LoadDataRow(values, LoadOption.OverwriteChanges);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    string.Format(Resources.ErrorGettingDesignTimeData, ex.ToString()),
                    Resources.EntityDataSourceErrorCaption,
                    MessageBoxButtons.OK, 
                    MessageBoxIcon.Warning, 
                    MessageBoxDefaultButton.Button1, 
                    MessageBoxOptions.DefaultDesktopOnly);
            }

            isSampleData = true;
            return result.DefaultView as IEnumerable;
        }

        private Type GetObjectType()
        {
            Type result;
            try
            {
                ITypeResolutionService typeService = null;
                typeService = (ITypeResolutionService)(_owner.Control.Site.GetService(typeof(ITypeResolutionService)));
                result = typeService.GetType(this._owner.TypeName, true, false);
            }
            catch
            {
                result = typeof(object);
            }
            return result;
        }


        /// <summary>
        /// Returns schema information corresponding to the properties
        /// of the entity business object.
        /// </summary>
        /// <remarks>
        /// All public properties are returned except for those marked
        /// with the <see cref="BrowsableAttribute">Browsable attribute</see>
        /// as False.
        /// </remarks>
        public override IDataSourceViewSchema Schema
        {
            get
            {
                return new ObjectSchema(
                  _owner.AssemblyName,
                  _owner.TypeName).GetViews()[0];
            }
        }

        /// <summary>
        /// Get a value indicating whether data binding can retrieve
        /// the total number of rows of data.
        /// </summary>
        public override bool CanRetrieveTotalRowCount
        {
            get { return true; }
        }

        /// <summary>
        /// Get a value indicating whether data binding can directly
        /// delete the object.
        /// </summary>
        /// <remarks>
        /// If this returns true, the web page must handle the
        /// <see cref="EntityDataSource.Delete">Delete</see>
        /// event.
        /// </remarks>
        public override bool CanDelete
        {
            get
            {
                Type objectType = GetObjectType();
                return typeof(EntityBase).IsAssignableFrom(objectType);
            }
        }

        /// <summary>
        /// Get a value indicating whether data binding can directly
        /// insert an instance of the object.
        /// </summary>
        /// <remarks>
        /// If this returns true, the web page must handle the
        /// <see cref="EntityDataSource.Insert">Insert</see>
        /// event.
        /// </remarks>
        public override bool CanInsert
        {
            get
            {
                Type objectType = GetObjectType();
                return typeof(EntityBase).IsAssignableFrom(objectType);
            }
        }

        /// <summary>
        /// Get a value indicating whether data binding can directly
        /// update or edit the object.
        /// </summary>
        /// <remarks>
        /// If this returns true, the web page must handle the
        /// <see cref="EntityDataSource.Update">Update</see>
        /// event.
        /// </remarks>
        public override bool CanUpdate
        {
            get
            {
                Type objectType = GetObjectType();
                return typeof(EntityBase).IsAssignableFrom(objectType);
            }
        }
        /// <summary>
        /// Gets a value indicating whether the data source supports
        /// paging of the data.
        /// </summary>
        public override bool CanPage
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Gets a value indicating whether the data source supports
        /// sorting.
        /// </summary>
        public override bool CanSort
        {
            get
            {
                return true;
            }
        }
    }
}

